package com.tgjorgoski.window;

import javax.swing.*;

import org.apache.log4j.Logger;

import com.tgjorgoski.repository.HibernatePersistManager;
import com.tgjorgoski.utils.IconResource;
import com.tgjorgoski.utils.ViewUtils;

import java.awt.event.*;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

public class SideNotesApp extends MyAppBar implements MouseMotionListener, ActionListener {
	private static final int COLLAPSED_WIDTH=4;
	private static final int EXPANDED_WIDTH=450;
	boolean expanded=false;
	Timer timer;
	int position = MyAppBar.RIGHT;
	int rightMostX, leftMostX;
	int appYposition;
	int appHeight;
	TrayIcon sknIcon;
	private static Logger logger = Logger.getLogger(SideNotesApp.class);
	
	ImageIcon sidekickUnlocked, sidekickLocked;
	CheckboxMenuItem unlockedMnuCB;
	
	private void setYPosAndHeight() {
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		leftMostX = 0;
		rightMostX = dim.width;
		Insets is = Toolkit.getDefaultToolkit().getScreenInsets(getGraphicsConfiguration());
		appYposition = is.top;
		appHeight = dim.height - is.bottom-is.top;
	}
	
	public HTMLView getView() {
		return mainView;
	}

	public void init() {
		mainView = new HTMLView(this);
		mainView.init();
		setYPosAndHeight();
		this.setUndecorated(true);
		//setResizable(true);
		setAlwaysOnTop(true);
		this.setTitle("SideNote Application Desktop Toolbar");
		
		
		unlockedMnuCB = new CheckboxMenuItem("Locked");
		unlockedMnuCB.setState(Session.isAppLockedByDefaultOn());
		unlockedMnuCB.addItemListener(new ItemListener() {
			@Override
			public void itemStateChanged(ItemEvent e) {
				boolean locked = unlockedMnuCB.getState();
				Session.setAppLocked(locked);
			}
		});
		MenuItem exit = new MenuItem("Exit");
		exit.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				Session.getHTMLView().exit();
			}
		});
		
		PopupMenu popupMenu = new PopupMenu();
		popupMenu.add(unlockedMnuCB);
		popupMenu.addSeparator();
		popupMenu.add(exit);
		
		SystemTray tray = SystemTray.getSystemTray();
		sidekickUnlocked = IconResource.getIconResource("book_green");
		ImageIcon locked = IconResource.getIconResource("emblem-readonly");
		sidekickLocked = IconResource.getOverlayedIcon(sidekickUnlocked, locked, 6, 8);
		sknIcon = new TrayIcon(sidekickUnlocked.getImage(), "SidekickNotes", popupMenu);
		sknIcon.addMouseListener(new MouseAdapter(){
			   public void mouseClicked(MouseEvent e) {
				   if (Session.isAppLockedByDefaultOn()) {
					   //show the app on the specific place
					   //but now in "normal window", which uses "close" button to close
					   //also remember the last window position
				   }
			   }
		});
		try {
			tray.add(sknIcon);
			updateLockedState();
			Session.addPropertyChangeListener(new PropertyChangeListener() {
				@Override
				public void propertyChange(PropertyChangeEvent evt) {
					if (evt.getPropertyName().equals(Session.PREF_LOCKED)) {
						updateLockedState();
					}
				}
			});
		} catch (AWTException e1) {
			logger.error("Problem with adding tray icon", e1);
		}
		
		
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				//centralPanel = new JPanel();
				//centralPanel.setBorder(new BevelBorder(BevelBorder.RAISED));
				//centralPanel.setOpaque(true);
				getContentPane().setLayout(new BorderLayout());
				getContentPane().add(mainView,BorderLayout.CENTER);

				//getContentPane().add(mainView,BorderLayout.CENTER);
				//setSize(COLLAPSED_WIDTH, 100);
				//setVisible(true);
				//this.getContentPane().add(new JTextArea(text), BorderLayout.CENTER);
				//setAsBar(getTitle(), position);
				//setVisible(false);
			}
		});

		addMouseMotionListener(this);
		timer = new Timer(100, this);
		timer.start();
		
		final FocusTraversalPolicy ftp = getFocusTraversalPolicy();
		setFocusTraversalPolicy(new FocusTraversalPolicy() {
			@Override
			public Component getLastComponent(Container container) {
				return ftp.getLastComponent(container);
			}
			@Override
			public Component getFirstComponent(Container container) {
				// TODO Auto-generated method stub
				return ftp.getFirstComponent(container);
			}
		
			@Override
			public Component getDefaultComponent(Container container) {
				return mainView.getEditor();
			}
		
			@Override
			public Component getComponentBefore(Container container, Component component) {
				return ftp.getComponentBefore(container, component);
			}
		
			@Override
			public Component getComponentAfter(Container container, Component component) {
				// TODO Auto-generated method stub
				return ftp.getComponentAfter(container, component);
			}
		});
		
		addContainerListener(new ContainerListener() {
		
			@Override
			public void componentRemoved(ContainerEvent e) {
			}
		
			@Override
			public void componentAdded(ContainerEvent e) {
				System.out.println(e.getComponent());
			}
		});
	}
	
	public void updateLockedState() {
		if(Session.isAppLockedByDefaultOn()) {
			sknIcon.setImage(sidekickLocked.getImage());
		} else {
			sknIcon.setImage(sidekickUnlocked.getImage());
		}
	}

	public static void main(String[] args) {
		// Create an instance of the application
		boolean windowLookAndFeel = true;
		if (windowLookAndFeel) {
			try {
				UIManager.setLookAndFeel(UIManager
						.getSystemLookAndFeelClassName());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		HibernatePersistManager.init();
		SideNotesApp sna = new SideNotesApp();
		Session.setApplication(sna);
		sna.init();
	}

	public void closeWindow() {
		System.exit(0);
	}
	
	HTMLView mainView; 
	
	private void changeToExpanded() {
		getFocus();
		mainView.setFocusOnEditor();
	}
	private void changeToCollapsed() {
		//getContentPane().removeAll();
		//FIXME:Return the focus to the previous window
	}


	
	//Show the app if the mouse moved on it, and it is not expanded
	public void mouseDragged(MouseEvent e) {
		Component comp = e.getComponent();
	}
	
	public void mouseMoved(MouseEvent e) {
	/*	if (e.getID()==MouseEvent.MOUSE_MOVED) {
			if (!expanded) {
				inside=true;
				timeInside=0;
			}
		}*/
	}

	boolean inside=false;
	int timeInside=0;
	static int TRIGGER_TIME=3;
	
	private Point oldMPoint;
	public void actionPerformed(ActionEvent e) {
		if (e.getSource()==timer) {
			Point mPoint = MouseInfo.getPointerInfo().getLocation();
			Rectangle dim = getBounds();
			Point p = new Point(mPoint.x-dim.x, mPoint.y-dim.y);
			if (!contains(p) && mPoint.x<=rightMostX-3 && !ViewUtils.isPopupMenuVisible()) {
				Window ww = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
				if (ww instanceof Dialog && ww!=this) return;
				inside=false;
				if (expanded) {
					expanded=false;
					SwingUtilities.invokeLater(new Runnable() {
						public void run() {
							changeToCollapsed();
							Rectangle dim = getBounds();
							getContentPane().invalidate();
							getContentPane().repaint();
							/*
							dim.width=COLLAPSED_WIDTH;
							if (position==MyAppBar.RIGHT) {
								dim.x=dim.x+EXPANDED_WIDTH-COLLAPSED_WIDTH;
							}
							setBounds(dim);*/	
							setVisible(false);
							returnFocus();
						}
					});
				}
			}
			if (mPoint.x>rightMostX-3 && !expanded) {
				inside=true;
				if (oldMPoint!=null) {
					if (oldMPoint.x!=mPoint.x || oldMPoint.y!=mPoint.y) {
						timeInside=0;
					}
				} else {
					timeInside=0;
				}
			} else {
				inside=false;
				timeInside=0;
			}
			oldMPoint=mPoint;
			if (inside) {
				timeInside++;
				if (timeInside>TRIGGER_TIME && !Session.isAppLockedByDefaultOn()) {
					timeInside=0;
					if (!expanded) {
						expanded=true;
						SwingUtilities.invokeLater(new Runnable() {
							public void run() {
								setYPosAndHeight();
								changeToExpanded();
								Rectangle dim = getBounds();
								getContentPane().invalidate();
								getContentPane().repaint();
								dim.y=appYposition;
								dim.width=EXPANDED_WIDTH;
								dim.height=appHeight;
								if (position==MyAppBar.RIGHT) {
									dim.x=rightMostX-EXPANDED_WIDTH;
								}
								setBounds(dim);	
								setVisible(true);
								setAlwaysOnTop(true);
							}
						});
					}					
				}
			}
		}
	}

}